#ifndef _DLIST_H_
#define _DLIST_H_

#include "mem_chunk.h"

typedef void z_destroy_notify (void *data);
typedef struct z_list z_list;
typedef struct z_list_node z_list_node;

/* @brief double-linked list.
 */
struct z_list
{
  z_list_node *head;
  z_list_node *tail;
};

/* @ brief node of a double-linked list
 */
struct z_list_node
{
  z_list_node *next;
  z_list_node *prev;
  void *data;
};

/* Allocate a double-linked list
 * @return a z_list
 */
z_list* z_list_alloc(void);

/* Destroy the contents of a double-linked list
 * @Warning never use this function with a list which makes use of the chunk
 * @param list a z_list
 */
void z_list_destroy(z_list *list, z_destroy_notify destroy_func)__attribute__((nonnull(1)));

/* Free a double-linked list
 * @param list a z_list
 */
void z_list_free(z_list *list);

/* Append to a double-linked list 
 * warning don't mix with z_list_append_chunk
 * @param list a z_list
 * @param data the data
 */
void z_list_append(z_list *list, void* data)__attribute__((nonnull(1)));

/* append to a double-linked list with chunk
 * @param list a z_list
 * @param data the data
 */

void z_list_append_chunk(z_list *list, void *data, z_mem_chunk *mem_chunk)__attribute__((nonnull(1,3)));

/* Prepend to a double-linked list
 * @param list a z_list
 * @param data the data
 */
void z_list_prepend(z_list *list, void *data) __attribute__((nonnull(1)));


/* Prepend to a double-linked list with chunk
 * @param list a z_list
 * @param data the data
 * @pre the z_mem_chunk msut return chunks with at least the size of z_list_node
 */
void z_list_prepend_chunk(z_list *list, void *data, z_mem_chunk *mem_chunk) __attribute__((nonnull(1,3)));


#endif /* _DLIST_H_ */


